package tutorial.lite_mod.system_use.auth_access;

import org.apache.ibatis.exceptions.PersistenceException;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.log4j.Logger;
import public_util.dao.PublicMiddleTableMapper;
import public_util.model.Const4PublicDataBase;
import public_util.model.PublicMiddleTable;
import public_util.model.ReturnData;
import public_util.pack_4_stable.tools.DateTool;
import public_util.servlet.ServletParent;
import system_api_4_trade.DuzikaiSpecialApplicationFactory;
import system_api_4_trade.SpecialApplicationAfter;
import system_api_4_trade.SpecialApplicationBefore;
import system_api_4_trade.dao.ApiPublicMiddleTableMapper;
import system_api_4_trade.util.ParameterTool;
import system_api_4_trade.util.sql.InsertTool;
import system_api_4_trade.util.sql.SelectTool;
import system_api_4_trade.util.sql.SqlImportTool;
import system_api_4_trade.util.tool_4_handle.NumberToolApi;
import system_api_4_trade.util.tool_4_handle.StringToolApi;
import system_api_4_trade.util.tool_4_handle.Tool_4_ServletApi;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.sql.SQLSyntaxErrorException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * 采用静态变量的方式来存储相关的IP,若干分钟后,批量写入进去
 * 传递特殊参数, 可以演示的模板部分
 * 后面大部分的配置, 都是前端自己传过来比较稳妥
 * 每个传参对应一个相应的方法
 */
public class TemplateUtilApi {

    private static Logger logger = Logger.getLogger(TemplateUtilApi.class);




    public static ReturnData generate_token_app_id(SqlSessionFactory sqlSession, ServletParent thisParent, HttpSession hsession, HttpServletResponse response, HttpServletRequest request){
        logger.info("----generate_token_app_id----");
        SqlSession session = sqlSession.openSession();
        /**全部为duzikai的Mapper**/
        ApiPublicMiddleTableMapper middleTableMapper = session.getMapper(ApiPublicMiddleTableMapper.class);
        ReturnData resultData = new ReturnData();
        HashMap<String, Object> returnRealData = new HashMap<String, Object>();
        resultData.setReturnData(returnRealData);

        String app_id = request.getParameter("app_id");
        String secret_code = request.getParameter("secret_code");

        app_id = StringToolApi.paraHttpFilter(app_id);
        secret_code = StringToolApi.paraHttpFilter(secret_code);

        if (app_id == null || secret_code == null)
        {
            resultData.setMsg("app_id和secret不能为空");
            logger.error(resultData.getMsg());
            return resultData;
        }

        try {
            HashMap<String,Object> param2db = new  HashMap<String, Object>();//需要传给DB的参数
            /**所有API参数处理-结束**/
            //需要传入待处理的MiddleTable名称
            String TABLE_NAME_4_MIDDLE = "public_middle_table_system_use_auth_access";
            SpecialApplicationBefore beforeApplication = DuzikaiSpecialApplicationFactory.load_before_application();
            ReturnData checkInject = ParameterTool.loadRequest2Para(beforeApplication,request, param2db, false);//看情况塞入即可, 透传到数据库层面
            if (checkInject.getStatus() != 0)
            {
                return checkInject;
            }
            param2db.put(SqlImportTool.TABLE_NAME_4_MIDDLE, TABLE_NAME_4_MIDDLE);//固定的


            /**所有API参数处理-结束**/
            /**前处理before操作-开始**/
            SpecialApplicationBefore beforeApplicaiton = DuzikaiSpecialApplicationFactory.load_before_application();
            if (beforeApplicaiton != null)
            {
                ReturnData specai_return = beforeApplicaiton.generate_token_app_id(request, resultData, session, param2db);
                if (specai_return != null && specai_return.getStatus() != 0)
                {
                    logger.error(specai_return.getMsg());
                    return specai_return;
                }
            }
            /**前处理before操作-结束**/



            /**中间核心部分动作-开始**/
            //获取到界面的基本信息


            String token = (String)param2db.get("pre_cmd_para_token");
            String pre_cmd_effect_time = (String)param2db.get("pre_cmd_effect_time");

            int effect_tive_time = (int) NumberToolApi.getFloatNumber(pre_cmd_effect_time);
            HashMap<String, Object> paraPrice = new HashMap<>();
            ReturnData returnData = generate_auth_info(session,middleTableMapper, token, app_id, secret_code, effect_tive_time, paraPrice);
            if (returnData != null && returnData.getStatus() != 0)
            {
                return returnData;
            }

            PublicMiddleTable middleTable = find_token_by_unique_key(middleTableMapper,token);
            if (middleTable == null)
            {
                resultData.setMsg("未能获取到相关的MiddleTable设置");
                return resultData;
            }

            /**后处理afther操作-开始**/
            SpecialApplicationAfter afterApplicaiton = DuzikaiSpecialApplicationFactory.load_after_application();
            if (afterApplicaiton != null)
            {
                ReturnData specai_return = afterApplicaiton.generate_token_app_id(request, resultData, session, param2db, middleTable);
                if (specai_return != null && specai_return.getStatus() != 0)
                {
                    logger.error(specai_return.getMsg());
                    return specai_return;
                }
            }

            returnRealData.put("token", middleTable.getUnique_key());
            /**后处理before操作-结束**/
            resultData.setStatus(0);
            return resultData;
        }
        catch (PersistenceException pe) {
            try {
                throw pe.getCause();
            } catch (SQLSyntaxErrorException se) {
                resultData.setMsg(SqlImportTool.showSQLSyntaxError(se));
                return resultData;
            } catch (Throwable throwable) {
                resultData.setMsg(throwable.getMessage());
                return resultData;
            }
        }
        catch(Exception e)
        {
            Tool_4_ServletApi.showStackTrace(e);
            resultData.setMsg("请检查数据异常");
            return resultData;

        }
        finally
        {
            session.close();
        }
    }




    /**
     * 日志信息的插入
     */
    public static ReturnData generate_auth_info(SqlSession session , ApiPublicMiddleTableMapper midMapper, String token, String appId, String secret, int effect_minute, HashMap<String, Object> paraPrice)
    {
        PublicMiddleTable table = find_app_id_and_secret(midMapper, appId, secret);
        ReturnData returnData = new ReturnData();
        if (table == null)
        {
            returnData.setMsg("系统不存在相关的appId和Secret");
            return returnData;
        }
        clean_before_app_id_secret(session, appId);//清理之前的appId内容
        paraPrice.put(Const4PublicDataBase.PARA_type_middle_app, 10001);
        paraPrice.put(Const4PublicDataBase.PARA_type_inner_app, 2002);
        paraPrice.put(Const4PublicDataBase.PARA_is_online, 0);
        paraPrice.put(Const4PublicDataBase.PARA_time_insert, DateTool.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
        paraPrice.put(Const4PublicDataBase.PARA_unique_key, token);//唯一字符, 每个项目各自生成比较合理
        paraPrice.put(Const4PublicDataBase.PARA_mid_table_remark_001, appId);//appID
        paraPrice.put(Const4PublicDataBase.PARA_mid_table_remark_002, secret);//secret
        paraPrice.put(Const4PublicDataBase.PARA_time_4_begin, DateTool.format(new Date(), "yyyy-MM-dd HH:mm:ss"));//secret
        Date data_after = DateTool.addMinute(new Date(), effect_minute);
        paraPrice.put(Const4PublicDataBase.PARA_time_4_end, DateTool.format(data_after, "yyyy-MM-dd HH:mm:ss"));//secret
        HashMap<String, Object> selMap = InsertTool.paramap2Insert(paraPrice, "public_middle_table_system_use_auth_access");
        midMapper.insertPublicMiddleTable(selMap);
        session.commit();
        return null;
        //在外面返回unique_key比较合理
    }



    //将该APP下面的所有生成的内容, 全部清理
    public static void clean_before_app_id_secret(SqlSession session, String appId)
    {
        HashMap<String, Object> paraData = new HashMap<String, Object>();
        paraData.put("search_type_middle_app", 10001);
        paraData.put("search_type_inner_app", 2002);
        paraData.put("search_mid_table_remark_001", appId+""); // 用户ID
        paraData.put(Const4PublicDataBase.TABLE_NAME_4_MIDDLE, "public_middle_table_system_use_auth_access");
        paraData.put(Const4PublicDataBase.PARA_is_online, 1);//清除
        PublicMiddleTableMapper midMapper = session.getMapper(PublicMiddleTableMapper.class);
        midMapper.updatePublicMiddleTable(paraData);
        session.commit();
    }



    /**
     * 查询token
     */
    public static PublicMiddleTable find_token_by_unique_key(ApiPublicMiddleTableMapper midMapper, String unique_key)
    {
        HashMap<String, Object> paraPrice = new HashMap<String, Object>();
        paraPrice.put(Const4PublicDataBase.PARA_type_middle_app, 10001);
        paraPrice.put(Const4PublicDataBase.PARA_type_inner_app, 2002);
        paraPrice.put(Const4PublicDataBase.PARA_is_online, 0);
        paraPrice.put(Const4PublicDataBase.PARA_unique_key + "_in", unique_key);
        paraPrice.put("pre_db_para_order_by_para", "id_public_middle_table DESC");//拿到最后生成的
        HashMap<String, Object>  realPara = SelectTool.paramap2selectMap(paraPrice, "public_middle_table_system_use_auth_access");
        List<PublicMiddleTable> listQianyuePrice = midMapper.tableDataList(realPara);//查询是否具备值
        if(listQianyuePrice == null || listQianyuePrice.size() == 0)
        {
            return null;
        }
        PublicMiddleTable currentTable = listQianyuePrice.get(0);
        //如果当前的table时间失效了, 则不需要过来折腾了
        return currentTable;
    }



    /**
     * 查询token
     */
    public static PublicMiddleTable find_app_id_and_secret(ApiPublicMiddleTableMapper midMapper, String appId, String secret)
    {
        HashMap<String, Object> paraPrice = new HashMap<String, Object>();
        paraPrice.put(Const4PublicDataBase.PARA_type_middle_app, 10001);
        paraPrice.put(Const4PublicDataBase.PARA_type_inner_app, 1001);
        paraPrice.put(Const4PublicDataBase.PARA_is_online, 0);
        paraPrice.put(Const4PublicDataBase.PARA_mid_table_remark_001, appId);//appID
        paraPrice.put(Const4PublicDataBase.PARA_mid_table_remark_002, secret);//secret
        HashMap<String, Object>  realPara = SelectTool.paramap2selectMap(paraPrice, "public_middle_table_system_use_auth_access");
        List<PublicMiddleTable> listQianyuePrice = midMapper.tableDataList(realPara);//查询是否具备值
        if(listQianyuePrice == null || listQianyuePrice.size() == 0)
        {
            return null;
        }
        if (listQianyuePrice.size() > 1)
        {
            logger.error("存在多个+ appId:" + appId);
            return null;
        }
        return listQianyuePrice.get(0);
    }





}
